<?php
namespace Model;



use Zend\InputFilter\InputFilter;

abstract class AbstractTable{
    /**
     * @var \Zend\Db\TableGateway\TableGateway
     */
    protected  $tableGateway;

    /**
     * @param \Zend\Db\TableGateway\TableGateway $tableGateway
     */
    public function setTableGateway($tableGateway)
    {
        $this->tableGateway = $tableGateway;
    }

    /**
     * @return \Zend\Db\TableGateway\TableGateway
     */
    public function getTableGateway()
    {
        return $this->tableGateway;
    }

    /**
     * @return \Zend\Db\ResultSet\ResultSet
     */

    public function fetchAll()
    {
        $resultSet = $this->tableGateway->select();
        return $resultSet;
    }

    public function getById($id){

        $resultSet = $this->tableGateway->select(array('id' => $id));
        return $resultSet->current();
    }

    /**
     * @param string $colName
     * @param string $val
     * @return \Zend\Db\ResultSet\ResultSet
     */
    public function getByColumn($colName, $val){

        $resultSet = $this->tableGateway->select(array($colName => $val));
        return $resultSet;
    }


    /**
     * @param string $colName
     * @param string $arr
     * @return \Zend\Db\ResultSet\ResultSet
     */
    public function getByMultiColumn($arr){

        $resultSet = $this->tableGateway->select($arr);
        return $resultSet;
    }


    public function delete($id)
    {
        $this->tableGateway->delete(array('id' => $id));
    }

    /**
     * @param array $data
     * @return int
     */
    public function insert($data){
        $this->tableGateway->insert($data);
        return  $this->tableGateway->lastInsertValue;
    }

    /**
     * @param array $data
     * @param integer $id
     */
    public function update($data, $id){
        $this->tableGateway->update($data, array('id' => $id));
    }

    /**
     * @return InputFilter
     */
    public  function getInputFilter(){
        $filter = new InputFilter();
        return $filter;
    }

    /**
     * @return \Zend\Db\Sql\Select
     */
    public function getDbSqlSelect(){
        $sql = $this->getTableGateway()->getSql();
        return $sql->select();
    }

    /**
     * @return \Zend\Db\Sql\Sql
     */
    public function getDbSql(){
        return $this->getTableGateway()->getSql();

    }

    /**
     * @param \Zend\Db\Sql\Select $select
     * @return \Zend\Db\Sql\Select
     */
    public function getCountSelect($select){
        $result = $select->reset($select::COLUMNS)
            ->reset($select::LIMIT)
            ->reset($select::OFFSET)
            ->reset($select::ORDER)
            ->columns(array('total' => new \Zend\Db\Sql\Expression('COUNT(*)')));
        return $result;
    }

    /**
     * @param \Zend\Db\Sql\Select $select
     * @return integer
     */
    public function getCount($select){
        $countSelect = $this->getCountSelect($select);
        $sql = $this->getDbSql();
        $statement = $sql->prepareStatementForSqlObject($countSelect);
        $result = $statement->execute()->current();
        return $result['total'];
    }

    /**
     * @return array
     * @description because return type of fetchAll method is ResultSet, which do not allow rewind operator,
     * so you can not reiterate the result. Use getAll method to do so.
     */
    public function getAll(){
        $resultSet = $this->fetchAll();
        $returnArr = array();
        foreach ($resultSet as $item) {
            $returnArr[] =  $item;
        }
        return $returnArr;
    }

    /**
     * @param \Zend\Db\Sql\Select $select
     * @return array
     */
    public function executeSelectForArray($select)
    {
        $resultSetInterface = $this->getTableGateway()->selectWith($select);
        $resultArr = array();
        foreach ($resultSetInterface as $anItem) {
           array_push($resultArr, $anItem);
        }
        return $resultArr;
    }

    public function getAllAsArray(){
        $resultSet = $this->fetchAll();
        $returnArr = array();
        foreach ($resultSet as $item) {
            $returnArr[] =  (array)$item;
        }
        return $returnArr;
    }

}